package org.alex.nettychat.netty.custom.handler;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.alex.nettychat.netty.custom.protocol.LoginRequestPacket;
import org.alex.nettychat.netty.custom.protocol.LoginResponsePacket;
import org.alex.nettychat.netty.custom.session.Session;
import org.alex.nettychat.netty.custom.utils.SessionUtil;

/**
 * SimpleChannelInboundHandler的使用非常简单。
 * 我们在继承这个类的时候，给它传递一个泛型参数，然后在channelRead0()方法里，
 * 不用再通过if逻辑来判断当前对象是否是本Handler可以处理的对象，也不用强转，
 * 不用往下传递本Handler处理不了的对象，这一切都已经交给父类SimpleChannelInboundHandler来实现，
 * 我们只需要专注于我们要处理的业务逻辑即可。
 *
 * @author : alex
 */
public class LoginRequestHandler extends SimpleChannelInboundHandler<LoginRequestPacket> {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, LoginRequestPacket loginRequestPacket) throws Exception {
        // 登录逻辑
        //构造响应包
        LoginResponsePacket loginResponsePacket = new LoginResponsePacket();
        loginResponsePacket.setVersion(loginRequestPacket.getVersion());
        // 登录校验
        if (valid(loginRequestPacket)) {
            //校验成功
            loginResponsePacket.setSuccess(true);
            System.out.println(loginRequestPacket.getUsername() + ":登录成功");
            Integer userId = loginRequestPacket.getUserId();
            loginResponsePacket.setUserId(userId);
            // 绑定session
            SessionUtil.bindSession(new Session(loginRequestPacket.getUserId(), loginRequestPacket.getUsername()), ctx.channel());
        } else {
            //校验失败
            loginResponsePacket.setReason("账号密码校验失败");
            loginResponsePacket.setSuccess(false);
        }

        // 登录响应
        ctx.channel().writeAndFlush(loginResponsePacket);
    }

    private boolean valid(LoginRequestPacket loginRequestPacket) {

        return true;
    }

    /**
     * 用户断线后取消Session
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        SessionUtil.unBindSession(ctx.channel());
    }
}
